// Copyright NVIDIA Corporation 2009
// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES


#include "sunsky.h"
#include "path_tracer.h"


using namespace optix;


rtDeclareVariable( optix::Ray,          ray,          rtCurrentRay, );
rtDeclareVariable(PerRayData_pathtrace, current_prd, rtPayload, );


rtDeclareVariable( float, sky_scale, , )=1.0f;

rtDeclareVariable(float3,       directional_light, , );
rtDeclareVariable(float3,       directional_light_col, , );
rtDeclareVariable(float,      solid_angle, , ) = 3.0e-2f * 100.0f;

RT_PROGRAM void miss()
{
  current_prd.done = true;

   if (dot( ray.direction, sky_up ) > 0.0f)
    {
      current_prd.radiance = querySkyModel(  false, ray.direction ) * sky_scale;

    // if the ray direction is within the sun's solid angle, return radiance of the sun
    float3 L = normalize(directional_light);
    float nDl = dot( ray.direction, L );
    if ( nDl > (1.0f - solid_angle / (2.0f * M_PIf)) )
    {
      // avoid double counting illumination
      current_prd.radiance += current_prd.countEmitted ? directional_light_col * (M_PIf / solid_angle) : make_float3(0.0f);
    }
  }
}

rtTextureSampler<float4, 2> envmap;
RT_PROGRAM void envmap_miss()
{
  current_prd.done = true;
  float theta = atan2f( ray.direction.x, ray.direction.y );
  float phi   = M_PIf * 0.5f -  acosf( ray.direction.z );
  float u     = (theta + M_PIf) * (0.5f * M_1_PIf);
  float v     = 0.5f * ( 1.0f + sin(phi) );
  current_prd.radiance = make_float3( tex2D(envmap, u, v) );

	//float3 L = normalize(directional_light);
 //   float nDl = dot( ray.direction, L );
 //   if ( nDl > (1.0f - solid_angle / (2.0f * M_PIf)) )
 //   {
 //     // avoid double counting illumination
 //     current_prd.radiance = current_prd.countEmitted ? make_float3( tex2D(envmap, u, v) ) * (M_PIf / solid_angle) : make_float3(0.0f);
 //   }
}
